<template>
  <div class="websocket-table">
    <div class="connection-status">
      连接状态: {{ connectionStatus }}
    </div>
    
    <div class="websocket-form">
      <input 
        v-model="wsUrl" 
        type="text" 
        placeholder="输入WebSocket地址"
      >
      <button @click="reconnectWebSocket" :disabled="isConnected">连接</button>
      <button @click="disconnectWebSocket" :disabled="!isConnected">断开</button>
    </div>
    
    <div class="message-form">
      <input 
        v-model="message" 
        type="text" 
        placeholder="输入要发送的消息"
        @keyup.enter="sendMessage"
      >
      <button @click="sendMessage" :disabled="!isConnected">发送</button>
    </div>
    
    <div v-if="lastSentMessage" class="message-display">
      <h3>发送的消息</h3>
      <div class="message-content">
        <p><strong>原文：</strong> {{ lastSentMessage }}</p>
        <p><strong>加密后：</strong> {{ lastEncryptedMessage }}</p>
      </div>
    </div>
    
    <div v-if="fullStreamContent" class="message-display">
      <h3>接收到的完整消息</h3>
      <div class="message-content">
        <p><strong>加密内容：</strong> {{ encryptedResponse }}</p>
        <p><strong>解密后：</strong> {{ fullStreamContent }}</p>
      </div>
    </div>
    
    <table v-if="tableData.length > 0">
      <thead>
        <tr>
          <th>标题</th>
          <th>内容</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="(item, index) in tableData" :key="index">
          <td>{{ item.title }}</td>
          <td>{{ item.content }}</td>
        </tr>
      </tbody>
    </table>
    
    <div v-else>
      等待数据...
    </div>
  </div>
</template>

<script>
import { decrypt, encrypt } from '../utils/crypto';

export default {
  name: 'WebSocketTable',
  data() {
    return {
      ws: null,
      connectionStatus: '未连接',
      tableData: [],
      message: '',
      isConnected: false,
      currentResponse: '',
      fullStreamContent: '',
      wsUrl: 'ws://10.10.31.193:8008/webSocketNew/kevin/1192/25011514094', // 默认WebSocket地址
      lastSentMessage: '', // 存储最后发送的原文
      lastEncryptedMessage: '', // 存储最后发送的加密内容
      encryptedResponse: '', // 存储接收到的加密内容
    };
  },
  mounted() {
    this.connectWebSocket();
  },
  beforeDestroy() {
    this.disconnectWebSocket();
  },
  methods: {
    parseStreamData(data) {
      let remainingData = this.currentResponse + data;
      let startIndex = 0;
      
      while (true) {
        // 查找下一个完整的JSON对象
        const start = remainingData.indexOf('{', startIndex);
        if (start === -1) break;
        
        const end = remainingData.indexOf('}', start) + 1;
        if (end === 0) break;
        
        try {
          // 尝试解析找到的JSON对象
          const jsonStr = remainingData.substring(start, end);
          const parsedData = JSON.parse(jsonStr);
          
          // 将解析成功的对象添加到表格
          this.tableData.push(parsedData);
          
          // 更新起始位置，继续查找下一个对象
          startIndex = end;
        } catch (e) {
          // 如果解析失败，可能是不完整的对象，移动到下一个位置
          startIndex = start + 1;
        }
      }
      
      // 保存剩余的数据
      this.currentResponse = remainingData.substring(startIndex);
    },
    
    connectWebSocket() {
      if (this.ws) {
        this.disconnectWebSocket();
      }
      
      try {
        this.ws = new WebSocket(this.wsUrl);
        
        this.ws.onopen = () => {
          this.connectionStatus = '已连接';
          this.isConnected = true;
        };
        
        this.ws.onmessage = (event) => {
          try {
            // 存储加密的响应
            this.encryptedResponse = event.data;
            
            // 解密数据
            const decryptedData = decrypt(event.data);
            
            // 处理流式数据
            if (decryptedData == '[DONE]') {
              console.log('完整的响应内容：', this.fullStreamContent);
              this.currentResponse = '';
              return;
            }

            // 累积完整的流式内容
            this.fullStreamContent += decryptedData;
            console.log('当前片段：', decryptedData);

            // 解析流式数据
            this.parseStreamData(decryptedData);
          } catch (error) {
            console.error('数据处理错误:', error);
          }
        };
        
        this.ws.onerror = (error) => {
          this.connectionStatus = '连接错误';
          this.isConnected = false;
          console.error('WebSocket错误:', error);
        };
        
        this.ws.onclose = () => {
          this.connectionStatus = '连接已关闭';
          this.isConnected = false;
        };
      } catch (error) {
        console.error('WebSocket连接错误:', error);
        this.connectionStatus = '连接错误';
      }
    },
    
    disconnectWebSocket() {
      if (this.ws) {
        this.ws.close();
        this.ws = null;
        this.isConnected = false;
        this.connectionStatus = '未连接';
      }
    },
    
    async reconnectWebSocket() {
      // 先断开现有连接
      this.disconnectWebSocket();
      
      // 等待一小段时间确保连接完全关闭
      await new Promise(resolve => setTimeout(resolve, 500));
      
      // 重新连接
      this.connectWebSocket();
    },
    
    async sendMessage() {
      if (!this.message.trim()) return;
      
      try {
        // 检查连接状态，如果断开则重新连接
        if (!this.isConnected || !this.ws || this.ws.readyState !== WebSocket.OPEN) {
          await this.reconnectWebSocket();
          // 等待连接建立
          await new Promise(resolve => {
            const checkConnection = setInterval(() => {
              if (this.isConnected) {
                clearInterval(checkConnection);
                resolve();
              }
            }, 100);
          });
        }
        
        // 发送新消息时才清空显示内容
        this.currentResponse = '';
        this.fullStreamContent = '';
        this.encryptedResponse = '';
        this.tableData = []; // 清空表格数据
        
        // 存储发送的消息
        this.lastSentMessage = this.message;
        
        // 加密消息
        const encryptedMessage = encrypt(this.message);
        this.lastEncryptedMessage = encryptedMessage;
        
        console.log('发送消息（原文）：', this.message);
        console.log('发送消息（加密后）：', encryptedMessage);
        
        // 发送加密后的消息
        this.ws.send(encryptedMessage);
        this.message = '';
      } catch (error) {
        console.error('发送消息失败:', error);
        // 发送失败时显示错误状态
        this.connectionStatus = '发送失败，请重试';
      }
    }
  }
};
</script>

<style scoped>
.websocket-table {
  padding: 20px;
}

.connection-status {
  margin-bottom: 20px;
  padding: 10px;
  background-color: #f5f5f5;
  border-radius: 4px;
}

.websocket-form {
  margin-bottom: 20px;
  display: flex;
  gap: 10px;
}

.websocket-form input {
  flex: 1;
  padding: 8px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

.websocket-form button {
  padding: 8px 16px;
  background-color: #4CAF50;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.websocket-form button:disabled {
  background-color: #cccccc;
  cursor: not-allowed;
}

.websocket-form button:hover:not(:disabled) {
  background-color: #45a049;
}

.message-form {
  margin-bottom: 20px;
  display: flex;
  gap: 10px;
}

.message-form input {
  flex: 1;
  padding: 8px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

.message-form button {
  padding: 8px 16px;
  background-color: #4CAF50;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.message-form button:disabled {
  background-color: #cccccc;
  cursor: not-allowed;
}

.message-form button:hover:not(:disabled) {
  background-color: #45a049;
}

table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 20px;
}

th, td {
  border: 1px solid #ddd;
  padding: 8px;
  text-align: left;
}

th {
  background-color: #f2f2f2;
}

tr:nth-child(even) {
  background-color: #f9f9f9;
}

.message-display {
  margin: 20px 0;
  padding: 15px;
  background-color: #f8f9fa;
  border-radius: 4px;
  border: 1px solid #dee2e6;
}

.message-display h3 {
  margin: 0 0 10px 0;
  color: #495057;
  font-size: 1.1em;
}

.message-content {
  background-color: white;
  padding: 10px;
  border-radius: 4px;
  border: 1px solid #e9ecef;
}

.message-content p {
  margin: 5px 0;
  word-break: break-all;
}

.message-content strong {
  color: #495057;
}
</style> 